import { ClientReady } from './ready';
/**
 * 音乐控件
 * 包含自动播放，退出页面自动暂停等逻辑
 *
 * **用法：**
 * @example
 * ```
 * const music = new Music(<HTMLAudioElement|MusicObject|string>audioObject,{autoplay:boolean=true});
 * ```
 */
export default class Music extends Promise<Music> {
  static get [Symbol.species]() {
    return Promise;
  }
  get [Symbol.toStringTag]() {
    return 'Music';
  }
  /**
   * ready监听，基于`clientReady`基础上增加手指触碰
   *
   * @param {Function} cb ready回调函数
   */
  public static ready(cb: Function) {
    const load = () => {
      document.documentElement.removeEventListener('touchstart', load);
      cb();
    };
    document.documentElement.addEventListener('touchstart', load);
    ClientReady.then(() => {
      cb();
    });
  }
  /* 静音状态 */
  private mute=true;
  /* autoplay状态 */
  private autoplay=true;
  private audioObject: HTMLAudioElement|MusicObject;
  /**
   * @param {MusicObject|HTMLAudioElement|string} audioObject 音频object
   * @param {MusicOption} audioOption 音频选项
   * - `autoplay`: 是否自动播放，默认：`true`
   * - `mute`: 是否静音，默认：`false`
   * - `loop`: 是否循环，默认：`false`
   */
  public constructor(
    audioObject: HTMLAudioElement|MusicObject|string,
    option: MusicOption = { autoplay: true, mute: false, loop: false },
  ) {
    super(async (resolve) => {
      let audio: HTMLAudioElement|MusicObject;
      if (typeof audioObject === 'string') {
        audio = new Audio();
        (audio as HTMLAudioElement).src = audioObject;
        (audio as HTMLAudioElement).loop = option.loop || false;
        document.documentElement.appendChild(audio as HTMLAudioElement);
      } else {
        if (audioObject instanceof Audio) audioObject.loop = option.loop || false;
        audio = audioObject;
      }
      // eslint-disable-next-line no-param-reassign
      audioObject = audio;
      Music.ready(() => {
        if (option.autoplay !== false && !option.mute) {
          (audioObject as HTMLAudioElement|MusicObject).play();
        } else {
          (audioObject as HTMLAudioElement|MusicObject).load();
        }
        resolve(this);
      });
    });
    this.mute = !!option.mute;
    this.autoplay = !!option.autoplay;
    this.audioObject = audioObject as HTMLAudioElement|MusicObject;
    this.watchInit();
  }
  /* 播放 */
  public play() {
    this.mute = false;
    this.audioObject.play();
  }
  /* 暂停 */
  public pause() {
    this.mute = true;
    this.audioObject.pause();
  }
  /* 监听是否退出到系统桌面 */
  private watchInit() {
    if (/android/i.test(navigator.userAgent)) {
      let timerPause: NodeJS.Timeout|null = null;
      const watch = () => {
        if (timerPause === null) {
          if (!this.mute && this.autoplay) {
            this.audioObject.play();
          }
        } else {
          clearTimeout(timerPause as NodeJS.Timeout);
        }
        timerPause = setTimeout(() => {
          timerPause = null;
          if (!this.mute) {
            this.audioObject.pause();
          }
        }, 200);
        requestAnimationFrame(watch);
      };
      watch();
    } else {
      window.addEventListener('focus', () => {
        if (!this.mute && this.autoplay) {
          this.audioObject.play();
        }
      });
      window.addEventListener('blur', () => {
        if (!this.mute) {
          this.audioObject.pause();
        }
      });
    }
  }
}
export interface MusicObject{
  load(): undefined;
  play(): undefined;
  pause(): undefined;
}
interface MusicOption{
  autoplay?: boolean;
  mute?: boolean;
  loop?: boolean;
}
